home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / advanced97 / highlight.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  16.2 KB  |  705 lines

  1. #include <math.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <GL/glut.h>
  5. #include "texture.h"
  6.  
  7. /* Some <math.h> files do not define M_PI... */
  8. #ifndef M_PI
  9. #define M_PI 3.14159265358979323846
  10. #endif
  11.  
  12. #if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2)
  13. #define glBindTexture glBindTextureEXT
  14. #endif
  15.  
  16. #define CHECK_ERROR(str)                                           \
  17. {                                                                  \
  18.     GLenum error;                                                  \
  19.     if(error = glGetError())                                       \
  20.        printf("GL Error: %s (%s)\n", gluErrorString(error), str);  \
  21. }
  22.  
  23. #ifndef FALSE
  24. enum {FALSE, TRUE};
  25. #endif
  26. enum {X, Y, Z, W};
  27. enum {OBJ_ANGLE, LIGHT_ANGLE, OBJ_TRANSLATE};
  28. enum {SURF_TEX, HIGHLIGHT_TEX};
  29.  
  30. /* window dimensions */
  31. int winWidth = 512;
  32. int winHeight = 512;
  33. int active;
  34. int dblbuf = TRUE;
  35. int highlight = TRUE;
  36. int gouraud = FALSE;
  37. int texmap = FALSE;
  38. int notex = FALSE; /* don't texture gouraud */
  39.  
  40. int object = 2;
  41. int maxobject = 2;
  42.  
  43. GLfloat lightangle[2] = {0.f, 0.f};
  44. GLfloat objangle[2] = {0.f, 0.f};
  45. GLfloat objpos[2] = {0.f, 0.f};
  46.  
  47. GLfloat color[4] = {1.f, 1.f, 1.f, 1.f};
  48. GLfloat zero[4] = {0.f, 0.f, 0.f, 1.f};
  49. GLfloat one[4] = {1.f, 1.f, 1.f, 1.f};
  50.  
  51. int texdim = 128;
  52. GLfloat *lighttex = 0;
  53. GLfloat lightpos[4] = {0.f, 0.f, 1.f, 0.f};
  54. GLboolean lightchanged[2] = {GL_TRUE, GL_TRUE};
  55. enum {UPDATE_OGL, UPDATE_TEX};
  56.  
  57.  
  58. /* draw a highly tesselated sphere with a specular highlight */
  59. void
  60. makeHighlight(int shinyness)
  61. {
  62.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  63.  
  64.     glPushMatrix(); /* starts as modelview */
  65.     glLoadIdentity();
  66.     glTranslatef(0.f, 0.f, -texdim/2.f);
  67.  
  68.     glMatrixMode(GL_PROJECTION);
  69.     glPushMatrix();
  70.     glLoadIdentity();
  71.     glOrtho(-texdim/2., texdim/2., -texdim/2., texdim/2., 0., texdim/2.);
  72.  
  73.     glPushAttrib(GL_LIGHTING_BIT|GL_VIEWPORT_BIT);
  74.     glViewport(0, 0, texdim, texdim);
  75.     glEnable(GL_LIGHTING);
  76.  
  77.     glLightfv(GL_LIGHT0, GL_DIFFUSE, zero);
  78.     glLightfv(GL_LIGHT0, GL_POSITION, lightpos); /* light direction */
  79.  
  80.     /* XXX TODO, range check an report errors */
  81.     glMateriali(GL_FRONT, GL_SHININESS, shinyness); /* cosine power */
  82.     glMaterialfv(GL_FRONT, GL_AMBIENT, zero); 
  83.     glMaterialfv(GL_FRONT, GL_DIFFUSE, zero); 
  84.     glMaterialfv(GL_FRONT, GL_SPECULAR, color);
  85.     glDisable(GL_TEXTURE_2D);
  86.  
  87.     glCallList(1);
  88.  
  89.     glEnable(GL_TEXTURE_2D);
  90.     glPopAttrib();
  91.     glPopMatrix();
  92.     glMatrixMode(GL_MODELVIEW);
  93.     glPopMatrix();
  94.  
  95.     glReadPixels(0, 0, texdim, texdim, GL_RGB, GL_FLOAT, lighttex);
  96.  
  97.     glBindTexture(GL_TEXTURE_2D, HIGHLIGHT_TEX);
  98.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  99.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texdim, texdim, 0, GL_RGB,
  100.          GL_FLOAT, lighttex);
  101. }
  102.  
  103. void
  104. reshape(int wid, int ht)
  105. {
  106.     winWidth = wid;
  107.     winHeight = ht;
  108.     glViewport(0, 0, wid, ht);
  109. }
  110.  
  111.  
  112. void
  113. motion(int x, int y)
  114. {
  115.  
  116.     switch(active)
  117.     {
  118.     case OBJ_ANGLE:
  119.     objangle[X] = (x - winWidth/2) * 360./winWidth;
  120.     objangle[Y] = (y - winHeight/2) * 360./winHeight;
  121.     glutPostRedisplay();
  122.     break;
  123.     case LIGHT_ANGLE:
  124.     lightangle[X] = (x - winWidth/2) * 2 * M_PI/winWidth;
  125.     lightangle[Y] = (winHeight/2 - y) * 2 * M_PI/winHeight;
  126.  
  127.     lightpos[Y] = sin(lightangle[Y]);
  128.     lightpos[X] = cos(lightangle[Y]) * sin(lightangle[X]);
  129.     lightpos[Z] = cos(lightangle[Y]) * cos(lightangle[X]);
  130.     lightpos[W] = 0.;
  131.     lightchanged[UPDATE_OGL] = GL_TRUE;
  132.     lightchanged[UPDATE_TEX] = GL_TRUE;
  133.     glutPostRedisplay();
  134.     break;
  135.     case OBJ_TRANSLATE:
  136.     objpos[X] = (x - winWidth/2) * 100./winWidth;
  137.     objpos[Y] = (winHeight/2 - y) * 100./winHeight;
  138.     glutPostRedisplay();
  139.     break;
  140.     }
  141. }
  142.  
  143. void
  144. mouse(int button, int state, int x, int y)
  145. {
  146.     if(state == GLUT_DOWN)
  147.     switch(button)
  148.     {
  149.     case GLUT_LEFT_BUTTON: /* move the light */
  150.         active = OBJ_ANGLE;
  151.         motion(x, y);
  152.         break;
  153.     case GLUT_MIDDLE_BUTTON:
  154.         active = LIGHT_ANGLE;
  155.         motion(x, y);
  156.         break;
  157.     case GLUT_RIGHT_BUTTON: /* move the polygon */
  158.         active = OBJ_TRANSLATE;
  159.         motion(x, y);
  160.         break;
  161.     }
  162. }
  163.  
  164. /* draw the object unlit without surface texture */
  165. void redraw_white(void)
  166. {
  167.     glPushMatrix(); /* assuming modelview */
  168.     glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
  169.     glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
  170.     glRotatef(objangle[Y], 1.f, 0.f, 0.f);
  171.     
  172.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  173.     
  174.     glDisable(GL_LIGHTING);
  175.     glDisable(GL_TEXTURE_2D);
  176.     /* draw the specular highlight */
  177.     
  178.     glCallList(object);
  179.  
  180.     glEnable(GL_TEXTURE_2D);
  181.  
  182.     glPopMatrix(); /* assuming modelview */
  183.  
  184.     CHECK_ERROR("OpenGL Error in redraw_tex()");
  185.  
  186.     if(dblbuf)
  187.     glutSwapBuffers(); 
  188.     else
  189.     glFlush(); 
  190. }
  191.  
  192.  
  193. /* just draw textured highlight */
  194. void redraw_tex_highlight(void)
  195. {
  196.     if(lightchanged[UPDATE_TEX])
  197.     {
  198.     makeHighlight(128);
  199.     lightchanged[UPDATE_TEX] = GL_FALSE;
  200.     }
  201.  
  202.  
  203.     glPushMatrix(); /* assuming modelview */
  204.     glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
  205.     glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
  206.     glRotatef(objangle[Y], 1.f, 0.f, 0.f);
  207.     
  208.     glClearColor(.1f, .1f, .1f, 1.f);
  209.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  210.     glClearColor(0.f, 0.f, 0.f, 1.f);
  211.     
  212.     /* draw the specular highlight */
  213.     glBindTexture(GL_TEXTURE_2D, HIGHLIGHT_TEX);
  214.     glEnable(GL_TEXTURE_GEN_S);
  215.     glEnable(GL_TEXTURE_GEN_T);
  216.     
  217.     glCallList(object);
  218.  
  219.     glDisable(GL_TEXTURE_GEN_S);
  220.     glDisable(GL_TEXTURE_GEN_T);
  221.  
  222.     glPopMatrix(); /* assuming modelview */
  223.  
  224.     CHECK_ERROR("OpenGL Error in redraw_tex()");
  225.  
  226.     if(dblbuf)
  227.     glutSwapBuffers(); 
  228.     else
  229.     glFlush(); 
  230. }
  231.  
  232. /* just draw opengl highlight */
  233. void redraw_gouraud_highlight(void)
  234. {
  235.     if(lightchanged[UPDATE_OGL])
  236.     {
  237.     glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  238.     lightchanged[UPDATE_OGL] = GL_FALSE;
  239.     }
  240.  
  241.     glPushAttrib(GL_LIGHTING);
  242.     glPushMatrix(); /* assuming modelview */
  243.     glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
  244.     glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
  245.     glRotatef(objangle[Y], 1.f, 0.f, 0.f);
  246.     
  247.     glClearColor(.1f, .1f, .1f, 1.f);
  248.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  249.     glClearColor(0.f, 0.f, 0.f, 1.f);
  250.     
  251.     /* draw the specular highlight */
  252.  
  253.     glEnable(GL_LIGHTING);
  254.     glDisable(GL_TEXTURE_2D);
  255.  
  256.     glMaterialfv(GL_FRONT, GL_SPECULAR, color); /* turn on ogl highlights */
  257.     glMaterialfv(GL_FRONT, GL_DIFFUSE, zero); /* turn off ogl diffuse */
  258.     glMaterialfv(GL_FRONT, GL_AMBIENT, zero); /* turn off ogl diffuse */
  259.  
  260.     /* draw the specular highlight */
  261.     glCallList(object);
  262.  
  263.     glEnable(GL_TEXTURE_2D);
  264.     glPopMatrix(); /* assuming modelview */
  265.     glPopAttrib();
  266.  
  267.     CHECK_ERROR("OpenGL Error in redraw_tex()");
  268.  
  269.     if(dblbuf)
  270.     glutSwapBuffers(); 
  271.     else
  272.     glFlush(); 
  273. }
  274.  
  275.  
  276.  
  277. /* show highlight texture map */
  278. void redraw_map(void)
  279. {
  280.     if(lightchanged[UPDATE_TEX])
  281.     {
  282.     makeHighlight(128);
  283.     lightchanged[UPDATE_TEX] = GL_FALSE;
  284.     }
  285.  
  286.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  287.  
  288.     glMatrixMode(GL_MODELVIEW);
  289.     glPushMatrix();
  290.     glLoadIdentity();
  291.  
  292.     glMatrixMode(GL_PROJECTION);
  293.     glPushMatrix();
  294.     glLoadIdentity();
  295.  
  296.     glBindTexture(GL_TEXTURE_2D, HIGHLIGHT_TEX);
  297.     glDisable(GL_LIGHTING);
  298.  
  299.     glBegin(GL_QUADS);
  300.     glTexCoord2i(0, 0);
  301.     glVertex2i(-1, -1);
  302.  
  303.     glTexCoord2i(1, 0);
  304.     glVertex2i(1, -1);
  305.  
  306.     glTexCoord2i(1, 1);
  307.     glVertex2i(1,  1);
  308.  
  309.     glTexCoord2i(0, 1);
  310.     glVertex2i(-1,  1);
  311.     glEnd();
  312.  
  313.     glEnable(GL_LIGHTING);
  314.  
  315.     glPopMatrix();
  316.     glMatrixMode(GL_MODELVIEW);
  317.     glPopMatrix();
  318.  
  319.     CHECK_ERROR("OpenGL Error in redraw_map()");
  320.  
  321.     if(dblbuf)
  322.     glutSwapBuffers(); 
  323.     else
  324.     glFlush(); 
  325. }
  326.  
  327.  
  328.  
  329. /* multipass, use texture to make highlight */
  330. void redraw_tex(void)
  331. {
  332.     if(lightchanged[UPDATE_TEX])
  333.     {
  334.     makeHighlight(128);
  335.     lightchanged[UPDATE_TEX] = GL_FALSE;
  336.     }
  337.     if(lightchanged[UPDATE_OGL])
  338.     {
  339.     glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  340.     lightchanged[UPDATE_OGL] = GL_FALSE;
  341.     }
  342.  
  343.     glPushMatrix(); /* assuming modelview */
  344.     glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
  345.     glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
  346.     glRotatef(objangle[Y], 1.f, 0.f, 0.f);
  347.     
  348.  
  349.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  350.     
  351.     /* draw the diffuse portion of the light */
  352.     glEnable(GL_LIGHTING);
  353.  
  354.     glBindTexture(GL_TEXTURE_2D, SURF_TEX);
  355.  
  356.     if(notex)
  357.     glDisable(GL_TEXTURE_2D);
  358.     glCallList(object);
  359.     if(notex)
  360.     glEnable(GL_TEXTURE_2D);
  361.  
  362.     glDisable(GL_LIGHTING);
  363.  
  364.     /* draw the specular highlight */
  365.     glEnable(GL_BLEND);
  366.     glBindTexture(GL_TEXTURE_2D, HIGHLIGHT_TEX);
  367.     glEnable(GL_TEXTURE_GEN_S);
  368.     glEnable(GL_TEXTURE_GEN_T);
  369.     glDepthFunc(GL_LEQUAL);
  370.     
  371.     glCallList(object);
  372.  
  373.     glDepthFunc(GL_LESS);
  374.     glDisable(GL_TEXTURE_GEN_S);
  375.     glDisable(GL_TEXTURE_GEN_T);
  376.     glDisable(GL_BLEND);
  377.  
  378.     glPopMatrix(); /* assuming modelview */
  379.  
  380.     CHECK_ERROR("OpenGL Error in redraw_tex()");
  381.  
  382.     if(dblbuf)
  383.     glutSwapBuffers(); 
  384.     else
  385.     glFlush(); 
  386. }
  387.  
  388. /* multipass; use opengl to make highlight */
  389. void redraw_phong(void)
  390. {
  391.     if(lightchanged[UPDATE_OGL])
  392.     {
  393.     glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  394.     lightchanged[UPDATE_OGL] = GL_FALSE;
  395.     }
  396.  
  397.     glPushAttrib(GL_LIGHTING);
  398.     glPushMatrix(); /* assuming modelview */
  399.     glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
  400.     glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
  401.     glRotatef(objangle[Y], 1.f, 0.f, 0.f);
  402.     
  403.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  404.     
  405.     /* draw the diffuse portion of the light */
  406.     glEnable(GL_LIGHTING);
  407.  
  408.     glBindTexture(GL_TEXTURE_2D, SURF_TEX);
  409.  
  410.     if(notex)
  411.     glDisable(GL_TEXTURE_2D);
  412.     glCallList(object);
  413.     if(notex)
  414.     glEnable(GL_TEXTURE_2D);
  415.  
  416.     /* turn off texturing so phong highlight color is pure */
  417.     glDisable(GL_TEXTURE_2D); 
  418.  
  419.     glMaterialfv(GL_FRONT, GL_SPECULAR, color); /* turn on ogl highlights */
  420.     glMaterialfv(GL_FRONT, GL_DIFFUSE, zero); /* turn off ogl diffuse */
  421.     glMaterialfv(GL_FRONT, GL_AMBIENT, zero); /* turn off ogl diffuse */
  422.  
  423.     /* draw the specular highlight */
  424.     glEnable(GL_BLEND);
  425.     glDepthFunc(GL_LEQUAL);
  426.     
  427.     glCallList(object);
  428.  
  429.     glEnable(GL_TEXTURE_2D); 
  430.     glDepthFunc(GL_LESS);
  431.     glDisable(GL_BLEND);
  432.  
  433.     glPopMatrix(); /* assuming modelview */
  434.     glPopAttrib();
  435.  
  436.     CHECK_ERROR("OpenGL Error in redraw_tex()");
  437.  
  438.     if(dblbuf)
  439.     glutSwapBuffers(); 
  440.     else
  441.     glFlush(); 
  442. }
  443.  
  444.  
  445. /* Use OpenGL lighting to get highlight */
  446. void redraw_original(void)
  447. {
  448.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  449.     
  450.     glPushMatrix(); /* assuming modelview */
  451.     glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
  452.     glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
  453.     glRotatef(objangle[Y], 1.f, 0.f, 0.f);
  454.     
  455.     if(lightchanged[UPDATE_OGL])
  456.     {
  457.     glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  458.     lightchanged[UPDATE_OGL] = GL_FALSE;
  459.     }
  460.  
  461.     glEnable(GL_LIGHTING);
  462.  
  463.     glBindTexture(GL_TEXTURE_2D, SURF_TEX);
  464.     glMaterialfv(GL_FRONT, GL_SPECULAR, color); /* turn on ogl highlights */
  465.     if(notex)
  466.     glDisable(GL_TEXTURE_2D);
  467.     glCallList(object);
  468.     if(notex)
  469.     glEnable(GL_TEXTURE_2D);
  470.     glMaterialfv(GL_FRONT, GL_SPECULAR, zero);
  471.  
  472.     glDisable(GL_LIGHTING);
  473.  
  474.     glPopMatrix(); /* assuming modelview */
  475.  
  476.     CHECK_ERROR("OpenGL Error in redraw()");
  477.  
  478.     if(dblbuf)
  479.     glutSwapBuffers(); 
  480.     else
  481.     glFlush(); 
  482. }
  483.  
  484. /* Draw with no highlight */
  485. void redraw_diffuse(void)
  486. {
  487.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  488.  
  489.     
  490.     glPushMatrix(); /* assuming modelview */
  491.     glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
  492.     glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
  493.     glRotatef(objangle[Y], 1.f, 0.f, 0.f);
  494.     
  495.     if(lightchanged[UPDATE_OGL])
  496.     {
  497.     glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  498.     lightchanged[UPDATE_OGL] = GL_FALSE;
  499.     }
  500.  
  501.     /* draw the diffuse portion of the light */
  502.     glEnable(GL_LIGHTING);
  503.  
  504.     glBindTexture(GL_TEXTURE_2D, SURF_TEX);
  505.     glCallList(object);
  506.  
  507.     glDisable(GL_LIGHTING);
  508.  
  509.     glPopMatrix(); /* assuming modelview */
  510.  
  511.     CHECK_ERROR("OpenGL Error in redraw()");
  512.  
  513.     if(dblbuf)
  514.     glutSwapBuffers(); 
  515.     else
  516.     glFlush(); 
  517. }
  518.  
  519. /* ARGSUSED1 */
  520. void key(unsigned char key, int x, int y)
  521. {
  522.     switch(key)
  523.     {
  524.     case 'u': /* unmodified highlight */
  525.     printf("Use unmodified gouraud highlight\n");
  526.     glutDisplayFunc(redraw_original);
  527.     glutPostRedisplay();
  528.     break;
  529.     case 'd':
  530.     printf("Draw diffuse only\n");
  531.     glutDisplayFunc(redraw_diffuse);
  532.     glutPostRedisplay();
  533.     break;
  534.     case 'g': /* separate gouraud shaded highlight */
  535.     printf("Use separate gouraud shaded highlight\n");
  536.     glutDisplayFunc(redraw_phong);
  537.     glutPostRedisplay();
  538.     break;
  539.     case 't': /* separate textured highlight */
  540.     printf("Use separate texture highlight\n");
  541.     glutDisplayFunc(redraw_tex);
  542.     glutPostRedisplay();
  543.     break;
  544.     case 'o':
  545.     /* toggle object type */
  546.     object++;
  547.     if(object > maxobject)
  548.         object = 2;
  549.     glutPostRedisplay();
  550.     break;
  551.     case 'm':
  552.     /* show highlight texture map */
  553.     printf("Show highlight texture map\n");
  554.     glutDisplayFunc(redraw_map);
  555.     glutPostRedisplay();
  556.     break;
  557.     case 'n':
  558.     if(notex)
  559.         notex = FALSE;
  560.     else
  561.         notex = TRUE;
  562.     glutPostRedisplay();
  563.     break;
  564.     case 'h':
  565.     printf("Show textured phong highlight\n");
  566.     glutDisplayFunc(redraw_tex_highlight);
  567.     glutPostRedisplay();
  568.     break;
  569.     case 'p':
  570.     printf("Show gouraud-shaded phong highlight\n");
  571.     glutDisplayFunc(redraw_gouraud_highlight);
  572.     glutPostRedisplay();
  573.     break;
  574.     case 'w':
  575.     printf("Show white object\n");
  576.     glutDisplayFunc(redraw_white);
  577.     glutPostRedisplay();
  578.     break;
  579.     case '\033':
  580.     exit(0);
  581.     break;
  582.     default:
  583.     fprintf(stderr, "Keyboard commands:\n\n"
  584.         "u - (unmodified opengl lighting)\n"
  585.         "d - diffuse only\n"
  586.         "g - multipass gouraud highlight\n"
  587.         "t - multipass texture highlight\n"
  588.         "o - toggle object\n"
  589.         "m - show highlight texture map\n"
  590.         "n - toggle surface texturing\n"
  591.         "h - show textured phong highlight\n"
  592.         "p - show gouraud-shaded phong highlight\n"
  593.         "w - show unlit white object\n");
  594.     break;
  595.     }
  596.  
  597. }
  598.  
  599.  
  600.  
  601. main(int argc, char *argv[])
  602. {
  603.     GLuint *tex;
  604.     int texwid, texht, texcomps;
  605.  
  606.     GLUquadricObj *quadric;
  607.  
  608.     glutInitWindowSize(winWidth, winHeight);
  609.     glutInit(&argc, argv);
  610.     if(argc > 1)
  611.     {
  612.     char *args = argv[1];
  613.     int done = FALSE;
  614.     while(!done)
  615.     {
  616.         switch(*args)
  617.         {
  618.         case 's': /* single buffer */
  619.         printf("Single Buffered\n");
  620.         dblbuf = FALSE;
  621.         break;
  622.         case '-': /* do nothing */
  623.         break;
  624.         case 0:
  625.         done = TRUE;
  626.         break;
  627.         }
  628.         args++;
  629.     }
  630.     }
  631.     if(dblbuf)
  632.     glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  633.     else
  634.     glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH);
  635.     (void)glutCreateWindow("example program");
  636.     glutDisplayFunc(redraw_original);
  637.     glutReshapeFunc(reshape);
  638.     glutMouseFunc(mouse);
  639.     glutMotionFunc(motion);
  640.     glutKeyboardFunc(key);
  641.  
  642.     /* draw a perspective scene */
  643.     glMatrixMode(GL_PROJECTION);
  644.     glFrustum(-100., 100., -100., 100., 300., 600.); 
  645.     glMatrixMode(GL_MODELVIEW);
  646.     /* look at scene from (0, 0, 450) */
  647.     gluLookAt(0., 0., 450., 0., 0., 0., 0., 1., 0.);
  648.  
  649.     /* turn on features */
  650.     glEnable(GL_DEPTH_TEST);
  651.  
  652.     glEnable(GL_TEXTURE_2D);
  653.     glEnable(GL_LIGHTING);
  654.     glEnable(GL_LIGHT0);
  655.     
  656.     glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  657.     glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  658.  
  659.     glMateriali(GL_FRONT, GL_SHININESS, 128); /* cosine power */
  660.  
  661.     /* remove back faces to speed things up */
  662.     glCullFace(GL_BACK);
  663.     glBlendFunc(GL_ONE, GL_ONE);
  664.  
  665.     lightchanged[UPDATE_TEX] = GL_TRUE;
  666.     lightchanged[UPDATE_OGL] = GL_TRUE;
  667.  
  668.     /* load pattern for current 2d texture */
  669.  
  670.     tex = read_texture("data/wood0.rgb", &texwid, &texht, &texcomps);
  671.  
  672.     gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, texwid, texht, GL_RGBA,
  673.               GL_UNSIGNED_BYTE, tex);
  674.     free(tex);
  675.     CHECK_ERROR("end of main");
  676.  
  677.     lighttex = (GLfloat *)malloc(texdim * texdim * sizeof(GL_FLOAT) * 3);
  678.  
  679.  
  680.  
  681.     /* XXX TODO use display list to avoid retesselating */
  682.     glNewList(1, GL_COMPILE);
  683.     glutSolidSphere((GLdouble)texdim/2., 50, 50);
  684.     glEndList();
  685.  
  686.  
  687.     glNewList(2, GL_COMPILE);
  688.     glutSolidTeapot(70.);
  689.     glEndList();
  690.  
  691.     quadric = gluNewQuadric();
  692.     gluQuadricTexture(quadric, GL_TRUE);
  693.  
  694.     glNewList(3, GL_COMPILE);
  695.     gluSphere(quadric, 70., 20, 20);
  696.     glEndList();
  697.  
  698.     gluDeleteQuadric(quadric);
  699.     maxobject = 3;
  700.  
  701.     glutMainLoop();
  702.  
  703.     return 0;
  704. }
  705.